package com.yuanqi.service.impl;

import com.yuanqi.domain.RetailProduct;
import com.yuanqi.domain.InventoryTransaction;
import com.yuanqi.domain.ProductStatus;
import com.yuanqi.domain.RetailInventoryAdjustment;
import com.yuanqi.repository.RetailProductRepository;
import com.yuanqi.repository.InventoryTransactionRepository;
import com.yuanqi.repository.RetailInventoryAdjustmentRepository;
import com.yuanqi.repository.RetailSalesOrderRepository;
import org.springframework.jdbc.core.JdbcTemplate;
import com.yuanqi.service.RetailProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 零售商品服务实现类
 */
@Slf4j
@Service
@Transactional
public class RetailProductServiceImpl implements RetailProductService {
    
    @Autowired
    private RetailProductRepository retailProductRepository;
    
    @Autowired
    private InventoryTransactionRepository inventoryTransactionRepository;
    
    @Autowired
    private RetailInventoryAdjustmentRepository retailInventoryAdjustmentRepository;
    
    @Autowired
    private RetailSalesOrderRepository retailSalesOrderRepository;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Override
    public RetailProduct createRetailProduct(RetailProduct retailProduct) {
        retailProduct.setCreatedAt(LocalDateTime.now());
        retailProduct.setUpdatedAt(LocalDateTime.now());
        return retailProductRepository.save(retailProduct);
    }
    
    @Override
    public RetailProduct updateRetailProduct(RetailProduct retailProduct) {
        retailProduct.setUpdatedAt(LocalDateTime.now());
        
        // 如果currentStock不为null，则同时更新product表的库存
        if (retailProduct.getCurrentStock() != null) {
            String updateProductStockSql = "UPDATE product SET stock = ? WHERE id = ?";
            int updatedRows = jdbcTemplate.update(updateProductStockSql, retailProduct.getCurrentStock(), retailProduct.getProductId());
            
            if (updatedRows == 0) {
                log.warn("更新商品库存失败，未找到对应的商品: productId={}", retailProduct.getProductId());
            } else {
                log.info("商品库存更新成功: productId={}, stock={}", retailProduct.getProductId(), retailProduct.getCurrentStock());
            }
        }
        
        return retailProductRepository.save(retailProduct);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<RetailProduct> findById(Long id) {
        Optional<RetailProduct> productOpt = retailProductRepository.findById(id);
        if (productOpt.isPresent()) {
            RetailProduct product = productOpt.get();
            fillProductBasicInfo(product);
            fillProductStockInfo(product);
            return Optional.of(product);
        }
        return productOpt;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<RetailProduct> findByProductId(Long productId) {
        Optional<RetailProduct> productOpt = retailProductRepository.findByProductId(productId);
        if (productOpt.isPresent()) {
            RetailProduct product = productOpt.get();
            fillProductBasicInfo(product);
            return Optional.of(product);
        }
        return productOpt;
    }
    
    
    @Override
    @Transactional(readOnly = true)
    public List<RetailProduct> findAll() {
        List<RetailProduct> products = retailProductRepository.findAll();
        // 为每个商品填充基本信息和库存信息
        for (RetailProduct product : products) {
            fillProductBasicInfo(product);
            fillProductStockInfo(product);
        }
        return products;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Page<RetailProduct> findAll(Pageable pageable) {
        Page<RetailProduct> page = retailProductRepository.findAll(pageable);
        
        // 为每个商品填充基本信息和库存信息
        for (RetailProduct product : page.getContent()) {
            fillProductBasicInfo(product);
            fillProductStockInfo(product);
        }
        
        return page;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<RetailProduct> findByStatus(ProductStatus status) {
        return retailProductRepository.findByStatus(status);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<RetailProduct> findByProductIdAndStatus(Long productId) {
        return retailProductRepository.findByProductIdAndStatus(productId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<RetailProduct> findLowStockProducts() {
        return retailProductRepository.findLowStockProducts();
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<RetailProduct> findOutOfStockProducts() {
        return retailProductRepository.findOutOfStockProducts();
    }
    
    @Override
    public RetailProduct adjustStock(Long retailProductId, Integer quantity, String reason, String operatorName) {
        Optional<RetailProduct> productOpt = retailProductRepository.findById(retailProductId);
        if (!productOpt.isPresent()) {
            throw new RuntimeException("零售商品不存在");
        }
        
        RetailProduct product = productOpt.get();
        Integer beforeBalance = product.getCurrentStock() != null ? product.getCurrentStock() : 0;
        Integer afterBalance = beforeBalance + quantity;
        
        log.info("库存调整计算: retailProductId={}, quantity={}, beforeBalance={}, afterBalance={}", 
            retailProductId, quantity, beforeBalance, afterBalance);
        
        if (afterBalance < 0) {
            throw new RuntimeException("库存不足，无法调整");
        }
        
        // 更新product表中的库存
        String updateProductStockSql = "UPDATE product SET stock = ? WHERE id = ?";
        log.info("执行库存更新SQL: {}, 参数: stock={}, productId={}", updateProductStockSql, afterBalance, product.getProductId());
        
        int updatedRows = jdbcTemplate.update(updateProductStockSql, afterBalance, product.getProductId());
        
        log.info("库存更新结果: 影响行数={}", updatedRows);
        
        if (updatedRows == 0) {
            throw new RuntimeException("更新商品库存失败，未找到对应的商品");
        }
        
        // 更新RetailProduct对象的currentStock字段（用于返回）
        product.setCurrentStock(afterBalance);
        
        // 记录库存交易
        InventoryTransaction transaction = new InventoryTransaction();
        transaction.setTxnCode("ADJ" + System.currentTimeMillis());
        transaction.setSkuId(product.getSkuId());
        transaction.setWarehouseId(1L); // 默认仓库ID
        transaction.setLocationId(1L); // 默认库位ID
        transaction.setQty(new BigDecimal(quantity));
        transaction.setTxnType(quantity > 0 ? "ADJ_IN" : "ADJ_OUT");
        transaction.setReferenceTable("retail_product");
        transaction.setReferenceId(retailProductId);
        transaction.setRemark(reason + " - " + operatorName);
        transaction.setCreatedAt(LocalDateTime.now());
        
        inventoryTransactionRepository.save(transaction);
        
        return product;
    }
    
    @Override
    public RetailProduct updateStatus(Long productId, ProductStatus status) {
        Optional<RetailProduct> productOpt = retailProductRepository.findByProductId(productId);
        if (!productOpt.isPresent()) {
            throw new RuntimeException("商品不存在");
        }
        
        RetailProduct product = productOpt.get();
        product.setStatus(status);
        product.setUpdatedAt(LocalDateTime.now());
        
        return retailProductRepository.save(product);
    }
    
    @Override
    public void deleteById(Long id) {
        retailProductRepository.deleteById(id);
    }
    
    @Override
    public void batchUpdateStatus(List<Long> productIds, ProductStatus status) {
        for (Long productId : productIds) {
            Optional<RetailProduct> productOpt = retailProductRepository.findById(productId);
            if (productOpt.isPresent()) {
                RetailProduct product = productOpt.get();
                product.setStatus(status);
                product.setUpdatedAt(LocalDateTime.now());
                retailProductRepository.save(product);
            }
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public Object getProductStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总商品数
        long totalProducts = retailProductRepository.count();
        statistics.put("totalProducts", totalProducts);
        
        // 启用商品数
        long activeProducts = retailProductRepository.findByStatus(ProductStatus.Active).size();
        statistics.put("activeProducts", activeProducts);
        
        // 禁用商品数
        long inactiveProducts = retailProductRepository.findByStatus(ProductStatus.Inactive).size();
        statistics.put("inactiveProducts", inactiveProducts);
        
        // 低库存商品数
        long lowStockProducts = retailProductRepository.findLowStockProducts().size();
        statistics.put("lowStockProducts", lowStockProducts);
        
        // 缺货商品数
        long outOfStockProducts = retailProductRepository.findOutOfStockProducts().size();
        statistics.put("outOfStockProducts", outOfStockProducts);
        
        // 今日库存交易数
        long todayTransactions = inventoryTransactionRepository.countTodayTransactions();
        statistics.put("todayTransactions", todayTransactions);
        
        // 本月库存交易数
        long monthTransactions = inventoryTransactionRepository.countMonthTransactions();
        statistics.put("monthTransactions", monthTransactions);
        
        return statistics;
    }
    
    @Override
    public Object getProductSalesStats(Long productId) {
        Map<String, Object> salesStats = new HashMap<>();
        
        try {
            // 获取商品信息
            Optional<RetailProduct> productOpt = retailProductRepository.findById(productId);
            if (!productOpt.isPresent()) {
                return salesStats;
            }
            
            RetailProduct product = productOpt.get();
            
            // 总销量 - 从销售订单中统计
            Long totalSales = retailSalesOrderRepository.countProductSales(productId);
            salesStats.put("totalSales", totalSales != null ? totalSales : 0);
            
            // 总销售额 - 从销售订单中统计
            Double totalRevenue = retailSalesOrderRepository.sumProductRevenue(productId);
            salesStats.put("totalRevenue", totalRevenue != null ? totalRevenue : 0.0);
            
            // 本月销量 - 从销售订单中统计本月数据
            Long monthlySales = retailSalesOrderRepository.countProductSalesThisMonth(productId);
            salesStats.put("monthlySales", monthlySales != null ? monthlySales : 0);
            
            // 本月销售额 - 从销售订单中统计本月数据
            Double monthlyRevenue = retailSalesOrderRepository.sumProductRevenueThisMonth(productId);
            salesStats.put("monthlyRevenue", monthlyRevenue != null ? monthlyRevenue : 0.0);
            
        } catch (Exception e) {
            // 如果查询失败，返回默认值
            salesStats.put("totalSales", 0);
            salesStats.put("totalRevenue", 0.0);
            salesStats.put("monthlySales", 0);
            salesStats.put("monthlyRevenue", 0.0);
        }
        
        return salesStats;
    }
    
    @Override
    public Object getProductInventoryHistory(Long productId) {
        List<Map<String, Object>> inventoryHistory = new ArrayList<>();
        
        try {
            // 从库存调整记录表中获取数据
            List<RetailInventoryAdjustment> adjustments = retailInventoryAdjustmentRepository
                .findByRetailProductIdOrderByAdjustmentDateDesc(productId);
            
            for (RetailInventoryAdjustment adjustment : adjustments) {
                Map<String, Object> record = new HashMap<>();
                
                // 根据调整类型设置记录类型和描述
                String type = "in";
                String description = "";
                String icon = "fas fa-plus";
                
                String adjustmentTypeStr = adjustment.getAdjustmentType();
                switch (adjustmentTypeStr) {
                    case "Sales Out":
                        type = "out";
                        description = "销售出库";
                        icon = "fas fa-shopping-cart";
                        break;
                    case "Return In":
                        type = "in";
                        description = "退货入库";
                        icon = "fas fa-undo";
                        break;
                    case "Manual In":
                        type = "in";
                        description = "手动入库";
                        icon = "fas fa-plus";
                        break;
                    case "Manual Out":
                        type = "out";
                        description = "手动出库";
                        icon = "fas fa-minus";
                        break;
                    case "Initial Stock":
                        type = "in";
                        description = "初始库存";
                        icon = "fas fa-box";
                        break;
                    case "Stock Take":
                        type = "adjust";
                        description = "库存盘点";
                        icon = "fas fa-clipboard-check";
                        break;
                    case "Transfer In":
                        type = "in";
                        description = "调拨入库";
                        icon = "fas fa-arrow-right";
                        break;
                    case "Transfer Out":
                        type = "out";
                        description = "调拨出库";
                        icon = "fas fa-arrow-left";
                        break;
                    default:
                        type = "adjust";
                        description = "其他调整";
                        icon = "fas fa-info";
                        break;
                }
                
                record.put("type", type);
                record.put("description", description);
                record.put("quantity", Math.abs(adjustment.getQuantityChange()));
                record.put("balance", adjustment.getQuantityAfter());
                record.put("timestamp", adjustment.getCreatedAt() != null ? adjustment.getCreatedAt() : adjustment.getAdjustmentDate().atStartOfDay());
                record.put("reason", adjustment.getReason());
                record.put("operator", adjustment.getCreatedBy() != null ? "操作员" + adjustment.getCreatedBy() : "系统");
                record.put("icon", icon);
                
                inventoryHistory.add(record);
            }
            
        } catch (Exception e) {
            // 如果查询失败，返回空列表
            log.error("获取库存变动记录失败: " + e.getMessage());
        }
        
        return inventoryHistory;
    }
    
    /**
     * 填充商品基本信息
     */
    private void fillProductBasicInfo(RetailProduct retailProduct) {
        try {
            String sql = "SELECT p.product_name, p.spu_code, p.image_url, s.sku_code " +
                       "FROM product p " +
                       "LEFT JOIN sku s ON p.id = s.product_id AND s.id = ? " +
                       "WHERE p.id = ?";
            
            List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, 
                retailProduct.getSkuId(), retailProduct.getProductId());
            
            if (!results.isEmpty()) {
                Map<String, Object> row = results.get(0);
                
                retailProduct.setProductName((String) row.get("product_name"));
                retailProduct.setProductCode((String) row.get("spu_code"));
                retailProduct.setSkuCode((String) row.get("sku_code"));
                retailProduct.setProductImage((String) row.get("image_url"));
            }
        } catch (Exception e) {
            log.error("填充商品基本信息失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 填充商品库存信息
     */
    private void fillProductStockInfo(RetailProduct retailProduct) {
        try {
            // 从product表获取库存信息
            String sql = "SELECT stock FROM product WHERE id = ?";
            
            List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, 
                retailProduct.getProductId());
            
            if (!results.isEmpty()) {
                Map<String, Object> row = results.get(0);
                
                Object stockObj = row.get("stock");
                Integer stock = null;
                if (stockObj != null) {
                    if (stockObj instanceof Number) {
                        stock = ((Number) stockObj).intValue();
                    } else if (stockObj instanceof String) {
                        try {
                            stock = Integer.parseInt((String) stockObj);
                        } catch (NumberFormatException e) {
                            log.warn("库存值格式错误: {}", stockObj);
                        }
                    }
                }
                
                retailProduct.setCurrentStock(stock);
            } else {
                retailProduct.setCurrentStock(0);
            }
        } catch (Exception e) {
            log.error("填充商品库存信息失败: " + e.getMessage(), e);
            retailProduct.setCurrentStock(0);
        }
    }
    
    /**
     * 更新商品图片URL
     */
    @Override
    public void updateProductImageUrl(Long productId, String imageUrl) {
        try {
            String sql = "UPDATE product SET image_url = ? WHERE id = ?";
            int updatedRows = jdbcTemplate.update(sql, imageUrl, productId);
            
            if (updatedRows == 0) {
                log.warn("商品图片URL更新失败，未找到对应的商品，productId: {}", productId);
            }
        } catch (Exception e) {
            log.error("更新商品图片URL失败: " + e.getMessage(), e);
            throw new RuntimeException("更新商品图片URL失败: " + e.getMessage(), e);
        }
    }
}
